package com.tgy.MyFlowable.workflow.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.convert.Convert;
import com.ctsi.core.common.entity.LoginUser;
import com.ctsi.core.common.util.$;
import com.ctsi.core.common.util.SecurityUtil;
import com.ctsi.core.workflow.enums.DelegateStatusEnum;
import com.ctsi.workflow.service.IFlwCommonService;
import com.ctsi.workflow.service.IFlwOptionService;
import com.ctsi.workflow.service.IFlwSubmitTaskService;
import com.ctsi.workflow.util.BpmCommentUtil;
import lombok.RequiredArgsConstructor;
import org.flowable.engine.FormService;
import org.flowable.engine.TaskService;
import org.flowable.task.api.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 任务提交业务实现类
 *
 * @version 1.0
 * @author: wang xiao xiang
 * @date: 2021/8/20 8:42
 */
@Service
@RequiredArgsConstructor
public class FlwSubmitTaskServiceImpl implements IFlwSubmitTaskService {

    /**
     * 使用此方式解决formService重名问题
     **/
    private final FormService formService;
    private final IFlwOptionService flwOptionService;
    private final TaskService taskService;
    private final IFlwCommonService flwCommonService;

    @Autowired
    private HttpServletRequest request;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void submit(String taskId, String comment, Map<String, Object> variables, String nextAssignee, String nextDueDate, Integer nextPriority) {
        //校验任务是否存在
        Task task = flwCommonService.queryTask(taskId);
        //获取流程定义id
        String processDefinitionId = task.getProcessDefinitionId();
        //获取流程实例id
        String processInstanceId = task.getProcessInstanceId();
        //获取当前操作人姓名
        String name = SecurityUtil.getUsername(request).getAccount();
        //生成提交意见
        comment = BpmCommentUtil.genSubmitComment(name, comment);
        //给任务添加意见
        flwCommonService.addComment(taskId, comment);
        if ($.isEmpty(variables)) {
            variables = CollectionUtil.newHashMap();
        }
        //如果是委托任务，需解决任务
        if ($.isNotNull(task.getDelegationState())) {
            if (DelegateStatusEnum.PENDING.toString().equals(task.getDelegationState().name())) {
                //解决任务并设置参数
                taskService.resolveTask(taskId, BeanUtil.beanToMap(variables));
            }
        } else {
            //获取当前操作人id
            LoginUser loginUser = SecurityUtil.getUsername(request);
            Long userId = loginUser.getId();
            //Long userId = MarsContextHolder.getUserId();
            String assignee = task.getAssignee();
            if ($.isEmpty(assignee)) {
                //设置办理人为当前用户
                taskService.setAssignee(taskId, Convert.toStr(userId));
            }
            //提交任务并设置参数
            if ($.isNotEmpty(nextAssignee)) {
                flwCommonService.complete(taskId, variables);
            }else{
                Map<String, String> newMap = variables.entrySet().stream()
                        .collect(Collectors.toMap(Map.Entry::getKey, e -> String.valueOf(e.getValue())));
                formService.submitTaskFormData(taskId, newMap);
//                flwCommonService.complete(taskId);
            }
        }
        //如果该流程设置了跳过相同处理人则自动完成
        boolean smartComplete = flwOptionService.getFlowableOptionSmartComplete(processDefinitionId);
        if (smartComplete) {
            flwCommonService.smartCompleteNext(processInstanceId);
        }

        //如果设定了下一任务审批人，则设置该审批人
        if ($.isNotEmpty(nextAssignee)) {
            flwCommonService.setNextAssignee(processInstanceId, nextAssignee);
        }

        //如果设定了下一任务审批期限，则设置审批期限
        if ($.isNotEmpty(nextDueDate)) {
            flwCommonService.setNextDueDate(processInstanceId, nextDueDate);
        }

        //如果设定了下一任务审批优先级，则设置审批优先级
        if ($.isNotEmpty(nextPriority)) {
            flwCommonService.setNextPriority(processInstanceId, nextPriority);
        }
    }

    @Override
    public void save(String taskId, Map<String, String> variables) {
        if ($.isEmpty(variables)) {
            variables = CollectionUtil.newHashMap();
        }
        formService.saveFormData(taskId, variables);
    }
}

